﻿// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

var dic = new Dictionary<int, Task<int>>();

Func<int, int> createValue = id =>
{
    Random random = new Random();
    var res = random.Next(0,10);
    Thread.Sleep(2000);
    Console.WriteLine($"生成当前ID{id}，值是{res}");
    return res;
};
Func<int, Task<int>> getDic = id =>
{
    lock (dic)
    {
        if (dic.TryGetValue(id, out var valueTask))
        {
            Console.WriteLine($"拿到当前{id},值是{valueTask}");//如果这里打印的是Task.Result，那么最终结果是先打印 “生成ID...”，当前的“拿到ID...”会被延后执行，相当于隐式await
            return valueTask;
        }

        else
            return dic[id] = Task.Run(() => createValue(id));
    }
        
            
};
var t = 0;
while(t<3){
    t++;
    for (var i = 0; i < 4; i++)
    {
        var id = i;
        Task.Run(() => getDic(id));
    }
}
Thread.Sleep(5000);
for(var i = 0; i < 4; i++)
{
    Console.WriteLine($"当前字典{i}，值是{dic[i].Result}");
}
Console.ReadLine();
